using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;

namespace WozLib.UI.Ink.SketchCommands
{
  [XmlInclude(typeof(UndoSketchCommands))]
  public class SketchCommandCollection
  {
    //[XmlAttribute("Name")]
    //private string _name = "bob";
    ///// <summary> 
    ///// Name of the preferences item 
    ///// </summary> 
    //public string Name
    //{
    //  get { return _name; }
    //  set { _name = value; }
    //} 

    //[
    //XmlArrayItem(Type = typeof(WozClientCommand)),
    //XmlArrayItem(Type = typeof(WozClientCreateCommand)),
    //]

    /// <summary>
    /// WozClientCommandList is only public for XML Serialization purposed
    /// It should not be modified directly. Instead use one of this classes methods.
    /// </summary>
    [XmlElement("WozClientCommandList")]
    public List<SketchCommand> WozClientCommandList
    {
      get
      {
        return _WozClientCommandList;
      }
      set
      {
        _WozClientCommandList = value;
      }
    } private List<SketchCommand> _WozClientCommandList;

    public SketchCommandCollection(SketchCommand wozClientCommand)
    {
      _WozClientCommandList = new List<SketchCommand>();
      _WozClientCommandList.Add(wozClientCommand);
    }

    public SketchCommandCollection()
    {
      _WozClientCommandList = new List<SketchCommand>();
    }

    public void SetWozClientCommand(SketchCommand wozClientCommand)
    {
      lock (_WozClientCommandList)
      {
        _WozClientCommandList.Clear();
        _WozClientCommandList.Add(wozClientCommand);
      }
    }

    public void AddWozClientCommand(SketchCommand wozClientCommand)
    {
      lock (_WozClientCommandList)
      {
        _WozClientCommandList.Add(wozClientCommand);
      }
    }

    public void AddWozClientCommand(IEnumerable<SketchCommand> wozClientCommands)
    {
      lock (_WozClientCommandList)
      {
        _WozClientCommandList.AddRange(wozClientCommands);
      }
    }

    public virtual void RedoAll()
    {
      // watch out for deadlock here
      // if one of these commands tries to modify this list we will deadlock
      lock (_WozClientCommandList)
      {
        foreach (SketchCommand wozClientCommand in _WozClientCommandList)
        {
          wozClientCommand.Redo();
        }
      }
    }

    public virtual void UndoAll()
    {
      // THIS COULD BE WRONG - might need to do iterate in other direction (LIFO)

      // watch out for deadlock here
      // if one of these commands tries to modify this list we will deadlock
      lock (_WozClientCommandList)
      {
        foreach (SketchCommand wozClientCommand in _WozClientCommandList)
        {
          wozClientCommand.Undo();
        }
      }
    }

    public void Clear()
    {
      _WozClientCommandList.Clear();
    }

    public void SetCommandReferences(SketchCommandReferences _ClientMirrorCommandReferences)
    {
      foreach (SketchCommand wozClientCommand in _WozClientCommandList)
      {
        wozClientCommand.WozClientCommandReferences = _ClientMirrorCommandReferences;
      }
    }

    public SketchCommandReferences GetCommandReferences()
    {
      SketchCommandReferences toReturn = null;

      foreach (SketchCommand wozClientCommand in _WozClientCommandList)
      {
        if (wozClientCommand.WozClientCommandReferences != null)
        {
          toReturn = wozClientCommand.WozClientCommandReferences;
          break;
        }        
      }

      return toReturn;
    }

    public SketchCommandCollection UndoCommand()
    {
      UndoSketchCommands wcuc = new UndoSketchCommands(this);
      return wcuc;
    }
  }
}
